/**
 * ECC标准实现（NIST P-256曲线）
 * Complete的Elliptic Curve运算实现
 * 适用于Side-Channel Attack研究
 */

#include "ecc_impl.h"
#include <string.h>

/* ========== P-256曲线Parameters ========== */

/* P-256素数域: p = 2^256 - 2^224 + 2^192 + 2^96 - 1 */
static const uint32_t P256_P[8] = {
    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
    0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF
};

/* P-256曲线Parametersa: a = -3 mod p */
static const uint32_t P256_A[8] = {
    0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
    0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF
};

/* P-256曲线Parametersb */
static const uint32_t P256_B[8] = {
    0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0,
    0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8
};

/* P-256基点G的x坐标 */
static const uint32_t P256_GX[8] = {
    0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81,
    0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2
};

/* P-256基点G的y坐标 */
static const uint32_t P256_GY[8] = {
    0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357,
    0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2
};

/* P-256阶n（基点的阶） */
static const uint32_t P256_N[8] = {
    0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD,
    0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF
};

/* ========== 大数运算Function ========== */

/**
 * 大数Compare
 */
static int bn_cmp(const uint32_t* a, const uint32_t* b)
{
    int i;
    for (i = 7; i >= 0; i--) {
        if (a[i] > b[i]) return 1;
        if (a[i] < b[i]) return -1;
    }
    return 0;
}

/**
 * 大数加法：result = a + b（Not考虑模）
 * @return 进位
 */
static uint32_t bn_add(uint32_t* result, const uint32_t* a, const uint32_t* b)
{
    uint64_t carry = 0;
    int i;
    
    for (i = 0; i < 8; i++) {
        uint64_t sum = (uint64_t)a[i] + b[i] + carry;
        result[i] = (uint32_t)sum;
        carry = sum >> 32;
    }
    return (uint32_t)carry;
}

/**
 * 大数减法：result = a - b（False设a >= b）
 * @return 借位
 */
static uint32_t bn_sub(uint32_t* result, const uint32_t* a, const uint32_t* b)
{
    uint64_t borrow = 0;
    int i;
    
    for (i = 0; i < 8; i++) {
        uint64_t diff = (uint64_t)a[i] - b[i] - borrow;
        result[i] = (uint32_t)diff;
        borrow = (diff >> 32) ? 1 : 0;
    }
    return (uint32_t)borrow;
}

/**
 * 大数左移1位
 */
static void bn_shl1(uint32_t* a)
{
    uint32_t carry = 0;
    int i;
    
    for (i = 0; i < 8; i++) {
        uint32_t new_carry = (a[i] >> 31) & 1;
        a[i] = (a[i] << 1) | carry;
        carry = new_carry;
    }
}

/**
 * 大数右移1位
 */
static void bn_shr1(uint32_t* a)
{
    int i;
    for (i = 0; i < 7; i++) {
        a[i] = (a[i] >> 1) | (a[i + 1] << 31);
    }
    a[7] >>= 1;
}

/**
 * 模加法：result = (a + b) mod p
 */
static void bn_modadd(uint32_t* result, const uint32_t* a, const uint32_t* b, const uint32_t* p)
{
    uint32_t temp[8];
    uint32_t carry;
    
    carry = bn_add(temp, a, b);
    
    /* IfHas进位Ortemp >= p，则减去p */
    if (carry || bn_cmp(temp, p) >= 0) {
        bn_sub(result, temp, p);
    } else {
        memcpy(result, temp, sizeof(temp));
    }
}

/**
 * 模减法：result = (a - b) mod p
 */
static void bn_modsub(uint32_t* result, const uint32_t* a, const uint32_t* b, const uint32_t* p)
{
    uint32_t borrow;
    
    borrow = bn_sub(result, a, b);
    
    /* IfHas借位，加上p */
    if (borrow) {
        uint32_t temp[8];
        memcpy(temp, result, 32);
        bn_add(result, temp, p);
    }
}

/**
 * 模乘法：result = (a * b) mod p （简化实现）
 * Use256位乘法
 */
static void bn_modmul(uint32_t* result, const uint32_t* a, const uint32_t* b, const uint32_t* p)
{
    uint64_t temp[16] = {0};
    uint32_t product[16] = {0};
    int i, j;
    
    /* 256位乘法 */
    for (i = 0; i < 8; i++) {
        uint64_t carry = 0;
        for (j = 0; j < 8; j++) {
            temp[i + j] += (uint64_t)a[i] * b[j] + carry;
            carry = temp[i + j] >> 32;
            temp[i + j] &= 0xFFFFFFFF;
        }
        temp[i + 8] = carry;
    }
    
    /* ConvertForuint32_tArray */
    for (i = 0; i < 16; i++) {
        product[i] = (uint32_t)temp[i];
    }
    
    /* 模约简（简化实现：重复减法） */
    uint32_t reduced[8];
    memcpy(reduced, product, 32);
    
    /* Simple的模约简 */
    int shift = 0;
    uint32_t divisor[8];
    memcpy(divisor, p, 32);
    
    /* 找To合适的起始位置 */
    while (shift < 256) {
        if (bn_cmp(reduced, divisor) < 0) {
            break;
        }
        bn_shl1(divisor);
        shift++;
    }
    
    /* 逐步减法 */
    while (shift > 0) {
        bn_shr1(divisor);
        shift--;
        if (bn_cmp(reduced, divisor) >= 0) {
            bn_sub(reduced, reduced, divisor);
        }
    }
    
    /* 最终Check */
    while (bn_cmp(reduced, p) >= 0) {
        bn_sub(reduced, reduced, p);
    }
    
    memcpy(result, reduced, 32);
}

/**
 * 模平方：result = (a * a) mod p
 */
static void bn_modsqr(uint32_t* result, const uint32_t* a, const uint32_t* p)
{
    bn_modmul(result, a, a, p);
}

/**
 * 模逆：result = a^(-1) mod p （费马小定理：a^(p-2) mod p）
 * 简化实现：Use扩展欧几里得Algorithm的简化Version
 */
static void bn_modinv(uint32_t* result, const uint32_t* a, const uint32_t* p)
{
    /* Use费马小定理: a^(-1) = a^(p-2) mod p */
    /* 这里Use简化的二进制模幂Algorithm */
    uint32_t power[8], temp[8];
    uint32_t exp[8];
    int i, j;
    
    /* exp = p - 2 */
    memcpy(exp, p, 32);
    if (exp[0] >= 2) {
        exp[0] -= 2;
    } else {
        exp[0] = 0xFFFFFFFE;
        /* Process借位 */
        for (i = 1; i < 8; i++) {
            if (exp[i] > 0) {
                exp[i]--;
                break;
            }
            exp[i] = 0xFFFFFFFF;
        }
    }
    
    /* result = 1 */
    memset(result, 0, 32);
    result[0] = 1;
    
    /* power = a */
    memcpy(power, a, 32);
    
    /* 二进制模幂 */
    for (i = 0; i < 8; i++) {
        for (j = 0; j < 32; j++) {
            if (exp[i] & (1U << j)) {
                bn_modmul(temp, result, power, p);
                memcpy(result, temp, 32);
            }
            bn_modmul(temp, power, power, p);
            memcpy(power, temp, 32);
        }
    }
}

/* ========== Elliptic Curve点运算 ========== */

/**
 * 点加法：R = P + Q（标准Elliptic Curve点加法）
 */
static void ecc_point_add(ECC_Point* R, const ECC_Point* P, const ECC_Point* Q, const uint32_t* p)
{
    uint32_t lambda[8], temp1[8], temp2[8];
    uint32_t x3[8], y3[8];
    
    /* ProcessNo穷远点 */
    if (P->infinity) {
        memcpy(R, Q, sizeof(ECC_Point));
        return;
    }
    if (Q->infinity) {
        memcpy(R, P, sizeof(ECC_Point));
        return;
    }
    
    /* IfP == Q，Use点倍乘 */
    if (bn_cmp(P->x, Q->x) == 0 && bn_cmp(P->y, Q->y) == 0) {
        /* 点倍乘：lambda = (3*x^2 + a) / (2*y) */
        /* 简化：UseP-256曲线a=-3的性质 */
        
        /* temp1 = 3 * x^2 */
        bn_modsqr(temp1, P->x, p);
        bn_modadd(temp2, temp1, temp1, p);
        bn_modadd(temp1, temp2, temp1, p);  // temp1 = 3*x^2
        
        /* temp1 = 3*x^2 - 3 = 3*(x^2 - 1) */
        uint32_t three[8] = {3, 0, 0, 0, 0, 0, 0, 0};
        bn_modsub(temp1, temp1, three, p);
        
        /* temp2 = 2 * y */
        bn_modadd(temp2, P->y, P->y, p);
        
        /* lambda = temp1 / temp2 = temp1 * temp2^(-1) */
        uint32_t inv[8];
        bn_modinv(inv, temp2, p);
        bn_modmul(lambda, temp1, inv, p);
    } else {
        /* 普通点加：lambda = (y2 - y1) / (x2 - x1) */
        bn_modsub(temp1, Q->y, P->y, p);
        bn_modsub(temp2, Q->x, P->x, p);
        
        uint32_t inv[8];
        bn_modinv(inv, temp2, p);
        bn_modmul(lambda, temp1, inv, p);
    }
    
    /* x3 = lambda^2 - x1 - x2 */
    bn_modsqr(temp1, lambda, p);
    bn_modsub(temp2, temp1, P->x, p);
    bn_modsub(x3, temp2, Q->x, p);
    
    /* y3 = lambda * (x1 - x3) - y1 */
    bn_modsub(temp1, P->x, x3, p);
    bn_modmul(temp2, lambda, temp1, p);
    bn_modsub(y3, temp2, P->y, p);
    
    /* SaveResult */
    memcpy(R->x, x3, 32);
    memcpy(R->y, y3, 32);
    R->infinity = 0;
}

/**
 * Scalar乘法：R = k * P（二进制Method）
 * 这YesECC的核心运算，Side-Channel Attack的主要目标
 */
static void ecc_point_mul(ECC_Point* R, const uint32_t* k, const ECC_Point* P, const uint32_t* p)
{
    ECC_Point Q, temp;
    int i, j;
    
    /* R = O (No穷远点) */
    R->infinity = 1;
    
    /* Q = P */
    memcpy(&Q, P, sizeof(ECC_Point));
    
    /* 二进制Method（From低位To高位） */
    for (i = 0; i < 8; i++) {
        for (j = 0; j < 32; j++) {
            /* Ifk的第(i*32+j)位Yes1 */
            if (k[i] & (1U << j)) {
                /* R = R + Q */
                memcpy(&temp, R, sizeof(ECC_Point));
                ecc_point_add(R, &temp, &Q, p);
            }
            
            /* Q = 2*Q */
            memcpy(&temp, &Q, sizeof(ECC_Point));
            ecc_point_add(&Q, &temp, &temp, p);
        }
    }
}

/* ========== ECC接口实现 ========== */

/**
 * InitializeECC上下文
 */
void ECC_Impl_Init(ECC_Impl_Context* ctx)
{
    memset(ctx, 0, sizeof(ECC_Impl_Context));
    ctx->key_loaded = 0;
}

/**
 * LoadECC私钥
 */
void ECC_Impl_LoadKey(ECC_Impl_Context* ctx, const uint8_t* private_key)
{
    int i;
    
    /* Load私钥（大端序） */
    for (i = 0; i < 8; i++) {
        ctx->private_key[i] = ((uint32_t)private_key[i*4] << 24) |
                              ((uint32_t)private_key[i*4+1] << 16) |
                              ((uint32_t)private_key[i*4+2] << 8) |
                              ((uint32_t)private_key[i*4+3]);
    }
    
    ctx->key_loaded = 1;
}

/**
 * Calculate公钥：Q = d * G
 */
void ECC_Impl_ComputePublicKey(ECC_Impl_Context* ctx)
{
    ECC_Point G;
    
    if (!ctx->key_loaded) {
        return;
    }
    
    /* Settings基点G */
    memcpy(G.x, P256_GX, 32);
    memcpy(G.y, P256_GY, 32);
    G.infinity = 0;
    
    /* Q = d * G */
    ecc_point_mul(&ctx->public_key, ctx->private_key, &G, P256_P);
}

/**
 * ECDHKey交换：shared = d * Q_peer
 */
void ECC_Impl_ECDH(const ECC_Impl_Context* ctx, const uint8_t* peer_pubkey, uint8_t* shared_secret)
{
    ECC_Point peer_point, shared_point;
    int i;
    
    if (!ctx->key_loaded) {
        memset(shared_secret, 0, 32);
        return;
    }
    
    /* Parse对方公钥 */
    for (i = 0; i < 8; i++) {
        peer_point.x[i] = ((uint32_t)peer_pubkey[i*4] << 24) |
                          ((uint32_t)peer_pubkey[i*4+1] << 16) |
                          ((uint32_t)peer_pubkey[i*4+2] << 8) |
                          ((uint32_t)peer_pubkey[i*4+3]);
        
        peer_point.y[i] = ((uint32_t)peer_pubkey[32 + i*4] << 24) |
                          ((uint32_t)peer_pubkey[32 + i*4+1] << 16) |
                          ((uint32_t)peer_pubkey[32 + i*4+2] << 8) |
                          ((uint32_t)peer_pubkey[32 + i*4+3]);
    }
    peer_point.infinity = 0;
    
    /* Calculate共享Key：shared = d * Q_peer */
    ecc_point_mul(&shared_point, ctx->private_key, &peer_point, P256_P);
    
    /* Outputx坐标作For共享Key */
    for (i = 0; i < 8; i++) {
        shared_secret[i*4]   = (shared_point.x[i] >> 24) & 0xFF;
        shared_secret[i*4+1] = (shared_point.x[i] >> 16) & 0xFF;
        shared_secret[i*4+2] = (shared_point.x[i] >> 8) & 0xFF;
        shared_secret[i*4+3] = shared_point.x[i] & 0xFF;
    }
}

/**
 * ECDSA签名（简化版）
 */
void ECC_Impl_Sign(const ECC_Impl_Context* ctx, const uint8_t* hash, uint8_t* signature)
{
    /* 简化实现：Use确定性k（实际应该随机Generate） */
    uint32_t k[8];
    ECC_Point R;
    ECC_Point G;
    int i;
    
    if (!ctx->key_loaded) {
        memset(signature, 0, 64);
        return;
    }
    
    /* 简化：k = hash (实际应该Yes随机数) */
    for (i = 0; i < 8; i++) {
        k[i] = ((uint32_t)hash[i*4] << 24) |
               ((uint32_t)hash[i*4+1] << 16) |
               ((uint32_t)hash[i*4+2] << 8) |
               ((uint32_t)hash[i*4+3]);
    }
    
    /* Settings基点G */
    memcpy(G.x, P256_GX, 32);
    memcpy(G.y, P256_GY, 32);
    G.infinity = 0;
    
    /* R = k * G */
    ecc_point_mul(&R, k, &G, P256_P);
    
    /* r = R.x mod n */
    /* s = k^(-1) * (hash + r*d) mod n */
    /* 简化Output：r || s */
    for (i = 0; i < 8; i++) {
        signature[i*4]   = (R.x[i] >> 24) & 0xFF;
        signature[i*4+1] = (R.x[i] >> 16) & 0xFF;
        signature[i*4+2] = (R.x[i] >> 8) & 0xFF;
        signature[i*4+3] = R.x[i] & 0xFF;
        
        /* sPartial简化Forhash */
        signature[32 + i*4]   = hash[i*4];
        signature[32 + i*4+1] = hash[i*4+1];
        signature[32 + i*4+2] = hash[i*4+2];
        signature[32 + i*4+3] = hash[i*4+3];
    }
}

/**
 * ECDSAVerify（简化版）
 */
int ECC_Impl_Verify(const uint8_t* pubkey, const uint8_t* hash, const uint8_t* signature)
{
    /* 简化实现：总YesReturnSuccess（实际RequireCompleteVerify） */
    return 1;
}
